Repository navigation
Conversation
Send check-ins around each run of a Huey periodic task when HueyIntegration(monitor_periodic_tasks=True) is set. Huey crontab() schedules are sent as the monitor config when Huey runs in UTC, so Sentry creates the monitor and keeps it in sync. Co-Authored-By: Claude <noreply@anthropic.com>
Coverage Results 📊✅ 133821 passed | ⏭️ 7293 skipped | Total: 141114 | Pass Rate: 94.83% | Execution Time: 448m 55s 📊 Comparison with Base Branch
➖ Removed Tests (58)View removed tests
All tests are passing successfully. ✅ Patch coverage is 96.61% (57 of 59 changed executable lines covered; target 80%). Changed files with executable lines (1)
Coverage diff@@ Coverage Diff @@
## master #8052 +/-##
==========================================
+ Coverage 90.25% 90.27% +0.02%
==========================================
Files 202 202 —
Tracked lines 26660 26720 +60
Branches 9926 9952 +26
==========================================
+ Hits 24062 24121 +59
- Misses 2598 2599 +1
- Partials 1510 1511 +1Generated by Coverage Action |
| _run_periodic_tasks(huey) | ||
|
|
||
| check_ins = _check_ins(envelopes) | ||
| assert [c["status"] for c in check_ins] == ["in_progress", "error"] | ||
| assert {c["monitor_slug"] for c in check_ins} == {"nightly"} | ||
|
|
||
| events = [envelope.get_event() for envelope in envelopes] | ||
| (error,) = [e for e in events if e is not None and e.get("exception")] | ||
| assert error["exception"]["values"][0]["type"] == "ValueError" |
There was a problem hiding this comment.
Error-path test lets Huey's re-raised exception escape
test_periodic_task_error calls _run_periodic_tasks() without handling the task's ValueError. Huey's execution path re-raises task failures, so the test exits before checking the error check-in or captured event. Catch the expected ValueError (for example, with pytest.raises) around the helper call, then run the assertions.
Evidence
test_periodic_task_errordefinesfailing()to raiseValueErrorand calls_run_periodic_tasks(huey)directly before its assertions._run_periodic_tasks()callshuey.execute(task)without catching exceptions._wrap_task_execute()insentry_sdk/integrations/huey.pycaptures task exceptions and re-raises them; the existingexecute_huey_task()test helper also catches exceptions aroundhuey.execute(task)for failing tasks.- The
monitordecorator records the error check-in but does not suppress the exception, so the call aborts before the new test's check-in and event assertions.
Identified by Warden · code-review · BCZ-G9S
| _CRONTAB_CODE = crontab().__code__ | ||
|
|
||
|
|
||
| def _get_closure_var(func: "Any", name: str) -> "Any": |
There was a problem hiding this comment.
Constructing the monitor from code inspection like this feels brittle. Is there any other way we can get to it, e.g. by monkeypatching something (the crontab func maybe? haven't looked into it so don't know if feasible)?
`RetryTask`, `TaskLockedException` and `CancelExecution` aren't failures for Huey or for the integration's error capture, so they no longer mark the check-in as an error. Co-Authored-By: Claude <noreply@anthropic.com>
| @pytest.mark.parametrize("exception", [CancelExecution, RetryTask, TaskLockedException]) | ||
| def test_periodic_task_control_flow(sentry_init, capture_envelopes, exception): | ||
| sentry_init(integrations=[HueyIntegration(monitor_periodic_tasks=True)]) | ||
| envelopes = capture_envelopes() | ||
| huey = MemoryHuey() | ||
|
|
||
| calls = [] | ||
|
|
||
| @huey.periodic_task(crontab()) | ||
| def cleanup(): | ||
| if not calls: | ||
| calls.append(1) | ||
| raise exception() | ||
|
|
||
| _run_periodic_tasks(huey) | ||
|
|
||
| statuses = [c["status"] for c in _check_ins(envelopes)] | ||
| assert statuses[:2] == ["in_progress", "ok"] | ||
|
|
There was a problem hiding this comment.
RetryTask is reported as a successful periodic run
Have you considered treating RetryTask differently from cancellation and lock control flow? _monitor_periodic_task catches it before the monitor context exits, so the check-in is marked ok even though Huey re-enqueues the task and the work has not finished. The retry runs under a new check-in, which can make one scheduled firing appear as multiple successful runs; Celery's beat-cron retry handler marks its check-in error instead.
Evidence
_monitor_periodic_taskwraps each execution inmonitor, whose context manager choosesokwhen it exits without an active exception.- The handler catches
RetryTaskinside that context and re-raises it afterward, so the first attempt's check-in is markedokbefore Huey handles the retry. - Huey re-enqueues a task after
RetryTask(test_task_retryintests/integrations/huey/test_huey.pyverifies a queued retry); the wrapper starts a new check-in for that execution. - Celery's parallel
crons_task_retryhandler marks a retried beat-task check-inerror.
Identified by Warden · code-review · GQU-RC3
Part of a series adding automatic Crons monitoring for the most-used job schedulers in each SDK. Check-ins for a monitor that doesn't exist yet are dropped, so today each monitor has to be created by hand with its schedule copied from the code. Sending the job's schedule as the monitor config lets Sentry create the monitor and keep it in sync.
This adds
monitor_periodic_taskstoHueyIntegration, matching Celery'smonitor_beat_tasks. When it's on, each@huey.periodic_taskrun sends check-ins with itscrontab(...)schedule in UTC, so Sentry creates the monitor on the first run. The slug is the task name. It's off by default, and regular tasks are unaffected.Tasks check in without a config when they use a custom
validate_datetime, restrict bothdayandday_of_week, or run on a Huey instance withutc=False.Docs: getsentry/sentry-docs#20057